﻿using QstkCore.DataAccess;
using QstkCore.Util;

namespace QstkCore.Domain
{
    public class StockPrices
    {
        public readonly float[] Prices;
        private readonly int tradingDays;

        public StockPrices(float[] prices)
        {
            tradingDays = prices.Length;
            Prices = prices;
        }

        private StockPrices(int tradingDays)
        {
            this.tradingDays = tradingDays;
            Prices = new float[tradingDays];
        }

        private void Set(int offset, float price)
        {
            Prices[offset] = price;
        }

        public StockPrices ReplaceNanFill(FillDirection method)
        {
            switch (method)
            {
                case FillDirection.Forward:
                    return ForwardFill();
                case FillDirection.Backward:
                    return BackwardFill();
                default:
                    return this;
            }
        }

        public StockPrices ForwardFill()
        {
            int lastRow = -1;
            for (int i = 0; i < tradingDays; i++)
                lastRow = Fill(i, lastRow);

            return this;
        }

        public StockPrices BackwardFill()
        {
            int lastRow = -1;
            for (int i = tradingDays - 1; i >= 0; i--)
                lastRow = Fill(i, lastRow);

            return this;
        }

        private int Fill(int currentRow, int previousRow)
        {
            if (previousRow >= 0)
            {
                if (float.IsNaN(Prices[currentRow]))
                    Prices[currentRow] = Prices[previousRow];
                return currentRow;
            }

            return currentRow;
        }

        public static StockPrices ReadStock(string symbol, string dataColumnName, TimeSeries dayOffsets)
        {
            var prices = new StockPrices(dayOffsets.Count);
            string filePath = DataAccess.DataAccess.GetInstance().GetFilePath(symbol);
            using (var csv = new CsvReader2(filePath))
            {
                while (csv.Read())
                {
                    var date = csv.GetDateTime("Date");
                    int offset = dayOffsets.GetOffsetDaysFromStart(date);
                    if (offset < 0)
                        continue;

                    var price = csv.GetFloat(dataColumnName);
                    prices.Set(offset, price);
                }
            }
            return prices;
        }
    }
}